package com.igd.security.realm;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AccountException;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import com.igd.business.service.IUserService;
import com.igd.common.constant.SessionConstant;
import com.igd.exceptions.IgdException;
import com.igd.exceptions.shiro.IncorrectCaptchaException;
import com.igd.exceptions.shiro.IncorrectPassWordException;
import com.igd.exceptions.shiro.IncorrectRoleException;
import com.igd.exceptions.shiro.InnerServerException;
import com.igd.security.Resources;
import com.igd.security.Roles;
import com.igd.security.User;
import com.igd.security.token.UsernamePasswordWithChceckCodeToken;
import com.igd.utils.DateUtil;

 /**
 * @version  1.0
 *
 * @author   QIAOYU
 *
 * @date     2013-6-19
 *
 * @description	 平台用户认证实现方法,使用数据库数据认证
 */

public class IgdDbRealm extends AuthorizingRealm {

	private Logger logger = Logger.getLogger(IgdDbRealm.class);
	
	private IUserService userService;
	
	/**
	 * 授权实现方法
	 */
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

		logger.info("已进行用户授权");
		
		if(null != principals){
			
			User user = (User) principals.fromRealm(getName()).iterator().next();
			
			if(null != user){
				
				SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
				
				List<Roles> roles = user.getUserRoles();
				
				for(Roles role : roles){
					
					if(StringUtils.isNotEmpty(role.getRolesCode())){
						
						info.addRole(role.getRolesCode());

					}
				}
				
				return info;
			}
		}
		
		return null;
	}

	/**
	 * 认证实现方法
	 */
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
		
		logger.info("用户合法信息认证");
		
		UsernamePasswordWithChceckCodeToken token = (UsernamePasswordWithChceckCodeToken) authcToken;

		logger.info(token.toString());

		String userName = token.getUsername();
		
		if(StringUtils.isNotEmpty(userName)){

			//表单提交的验证码
			String captcha = token.getCaptcha();

			//session中存入的验证码
			String captchaInSession = (String) SecurityUtils.getSubject().getSession().getAttribute(SessionConstant.LOGIN_RANDOM_KEY);

			if(StringUtils.isNotEmpty(captcha) && StringUtils.isNotEmpty(captchaInSession)){
				
				if(!captcha.equalsIgnoreCase(captchaInSession)){

					throw new IncorrectCaptchaException("验证码验证错误");

				}else{
					
					try {
						
						User user = this.getUserService().getUserInfoByUserName(userName);
						
						if(null != user){
							
							if(new String(token.getPassword()).equals(user.getUserPwd())){
								
								List<Roles> roles = this.getUserService().getUserRoleByUserId(user.getUserId());

								List<Resources> resources = this.getUserService().getUserRoleResourceByUserId(user.getUserId());
								
								if(null != roles && null != resources){
									
									user.setUserRoles(roles);
									
									for(Roles role : roles){
										
										String roleId = role.getRolesId();

										List<Resources> currentRoleRes = new ArrayList<Resources>();
										
										for(Resources res : resources){
											
											if(roleId.equals(res.getResRoleId())){

												currentRoleRes.add(res);

											}
										}
										
										role.setRoleResources(currentRoleRes);

									}
									
									SecurityUtils.getSubject().getSession().setAttribute(SessionConstant.LOGIN_USER_KEY,user);
									
									user.setUserLastLoginTime(DateUtil.getLongDate());
									
									this.getUserService().updateUserInfo(user);
									
									return new SimpleAuthenticationInfo(user,user.getUserPwd(),this.getName());
									
								}else{
									
									throw new IncorrectRoleException("未给["+userName+"]分配权限");

								}
								
							}else{
								
								throw new IncorrectPassWordException("用户密码校验失败");
								
							}
							
						}else{
							
							throw new AccountException("未找到["+userName+"]此用户");
							
						}
						
					} catch (SQLException e) {
						
						logger.error(e.getMessage());
						
						throw new InnerServerException("用户名不能为空");
						
					} catch (IgdException e) {
						
						logger.error(e.getMessage());

						throw new InnerServerException(e.getMessage());

					}
				}
			}
			
		}else{
			
			throw new AccountException("用户名不能为空");

		}
		
		return null;
	}

	public IUserService getUserService() {
		return userService;
	}

	public void setUserService(IUserService userService) {
		this.userService = userService;
	}
}
